package com.adinall.dsp.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 时间工具类
 * 
 * @author 高万超
 * @version V1.0.0 $ 2016年11月29日 下午11:04:54
 */
public final class DateUtils {

    /** 日期格式：yyyy-MM-dd */
    public static final String PATTERN_yyyy_MM_dd = "yyyy-MM-dd";

    /** 日期格式：yyyyMMddHHmmssS */
    public static final String PATTERN_yyyyMMddHHmmssS = "yyyyMMddHHmmssS";

    /** 日期格式：yyyy-MM-dd HH:mm:ss */
    public static final String PATTERN_yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
    
    /** 日期格式：yyyyMMdd_HHmmss */
    public static final String PATTERN_yyyyMMdd_HHmmss = "yyyyMMdd_HHmmss";

    /** 一秒钟毫秒数 */
    public static final int MILLIS_A_SECOND = 1000;

    /** 一分钟毫秒数 */
    public static final int MILLIS_A_MINUTE = 60000;

    /** 一小时毫秒数 */
    public static final int MILLIS_A_HOUR = 3600000;

    /** 一天毫秒数 */
    public static final int MILLIS_A_DAY = 86400000;

    /** 一天秒数 */
    public static final int SECOND_A_DAY = 86400;

    /** 每月天数 */
    public static final int[] MONTH_DAYS = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 29 };

    /**
     * 格式化时间
     * 
     * @param date
     *            时间
     * @param pattern
     *            格式
     * @return String 时间格式化
     */
    public static String format(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 字符串转为时间
     * 
     * @param str
     *            字符串
     * @param pattern
     *            格式
     * @return Date 时间
     */
    public static Date parse(String str, String pattern) {
        try {
            return new SimpleDateFormat(pattern).parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 日期相差天数
     * 
     * @param d0
     *            日期1
     * @param d1
     *            日期2
     * @return int 相差天数
     */
    public static int diffDay(Date d0, Date d1) {

        if (CheckUtils.isNull(d0) || CheckUtils.isNull(d1)) {
            return 0;
        }

        return (int) ((d0.getTime() - d1.getTime()) / MILLIS_A_DAY);
    }

    /**
     * 获取星期一日期
     * 
     * @param weekCount
     *            周数：0-本周星期一；-1-上周星期一；1-下周星期一；类推
     * @return Calendar 星期一
     */
    public static Calendar monday(int weekCount) {
        return anyDay(weekCount, Calendar.MONDAY);
    }

    /**
     * 获取星期二日期
     * 
     * @param weekCount
     *            周数：0-本周星期二；-1-上周星期二；1-下周星期二；类推
     * @return Calendar 星期二
     */
    public static Calendar tuesday(int weekCount) {
        return anyDay(weekCount, Calendar.TUESDAY);
    }

    /**
     * 获取星期三日期
     * 
     * @param weekCount
     *            周数：0-本周星期三；-1-上周星期三；1-下周星期三；类推
     * @return Calendar 星期三
     */
    public static Calendar wednesday(int weekCount) {
        return anyDay(weekCount, Calendar.WEDNESDAY);
    }

    /**
     * 获取星期四日期
     * 
     * @param weekCount
     *            周数：0-本周星期四；-1-上周星期四；1-下周星期四；类推
     * @return Calendar 星期四
     */
    public static Calendar thursday(int weekCount) {
        return anyDay(weekCount, Calendar.THURSDAY);
    }

    /**
     * 获取星期五日期
     * 
     * @param weekCount
     *            周数：0-本周星期五；-1-上周星期五；1-下周星期五；类推
     * @return Calendar 星期五
     */
    public static Calendar friday(int weekCount) {
        return anyDay(weekCount, Calendar.FRIDAY);
    }

    /**
     * 获取星期六日期
     * 
     * @param weekCount
     *            周数：0-本周星期六；-1-上周星期六；1-下周星期六；类推
     * @return Calendar 星期六
     */
    public static Calendar saturday(int weekCount) {
        return anyDay(weekCount, Calendar.SATURDAY);
    }

    /**
     * 获取星期日日期
     * 
     * @param weekCount
     *            周数：0-本周星期日；-1-上周星期日；1-下周星期日；类推
     * @return Calendar 星期日
     */
    public static Calendar sunday(int weekCount) {

        // 西方以星期日为第一天
        return anyDay(weekCount + 1, Calendar.SUNDAY);
    }

    private static Calendar anyDay(int weekCount, int weekDay) {

        Calendar c = Calendar.getInstance();

        c.add(Calendar.DATE, weekCount * 7);
        c.set(Calendar.DAY_OF_WEEK, weekDay);

        return c;
    }

    /**
     * 获取当月最大天数
     * 
     * @param year
     *            年
     * @param month
     *            月
     * @return int 最大天数
     */
    public static int day(int year, int month) {

        if (month != 2) {
            return MONTH_DAYS[month - 1];
        }

        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return 29;
        }

        return MONTH_DAYS[month - 1];
    }

    /**
     * 当前日期
     *
     * @return 系统当前时间
     */
    public static Date now() {
        return new Date();
    }
}